#include <string.h>
#include <iostream>
#include "afn0dparser.h"

#define callx_Afn0dParser_parseFx(AP,x)\
	call[x] = &AP##Afn0dParser::parseF##x\

#define Afn0dfx_Afn0dFParser_Fx(AP,x)\
AP##Afn0df##x& AP##Afn0dParser::F##x(uint16_t pn)\
{\
	umap[x][pn].F##x.Fn(x);\
	return umap[x][pn].F##x;\
}\

#define int_Afn0dFParser_parseFx(AP,x)\
int AP##Afn0dParser::parseF##x(uint8_t* data)\
{\
	AP##Afn0df##x& f = *(AP##Afn0df##x*)data;\
\
	umap[f.Fn()][f.Pn()].F##x = f;\
\
	return f.length();\
}\

#define AFN0D_PARSER_IMPLEMENTATION(AP) \
AP##Afn0dParser::AP##Afn0dParser(void)\
{\
	memset(call, 0, sizeof(call));\
	callx_Afn0dParser_parseFx(AP,1);\
	callx_Afn0dParser_parseFx(AP,2);\
	callx_Afn0dParser_parseFx(AP,3);\
	callx_Afn0dParser_parseFx(AP,4);\
	callx_Afn0dParser_parseFx(AP,5);\
	callx_Afn0dParser_parseFx(AP,6);\
	callx_Afn0dParser_parseFx(AP,7);\
	callx_Afn0dParser_parseFx(AP,8);\
}\
void AP##Afn0dParser::clear(void)\
{\
	umap.clear();\
}\
void AP##Afn0dParser::get(Mapmss& m)\
{\
	for(UnionMap::iterator A = umap.begin(); A != umap.end(); A++)\
	{\
		map<uint16_t,Union>::iterator B;\
		for(B = A->second.begin(); B != A->second.end(); B++)\
		{\
			switch(A->first)\
			{\
			case 1: B->second.F1.get(m); break;\
			case 2: B->second.F2.get(m); break;\
			case 3: B->second.F3.get(m); break;\
			case 4: B->second.F4.get(m); break;\
			case 5: B->second.F5.get(m); break;\
			case 6: B->second.F6.get(m); break;\
			case 7: B->second.F7.get(m); break;\
			case 8: B->second.F8.get(m); break;\
			}\
		}\
	}\
}\
bool AP##Afn0dParser::set(Mapmss& m)\
{\
	return false;\
}\
bool AP##Afn0dParser::append(Buffer& b)\
{\
	for(UnionMap::iterator A = umap.begin(); A != umap.end(); A++)\
	{\
		map<uint16_t,Union>::iterator B;\
		for(B = A->second.begin(); B != A->second.end(); B++)\
		{\
			switch(A->first)\
			{\
			case 1: b << B->second.F1; break;\
			case 2: b << B->second.F2; break;\
			case 3: b << B->second.F3; break;\
			case 4: b << B->second.F4; break;\
			case 5: b << B->second.F5; break;\
			case 6: b << B->second.F6; break;\
			case 7: b << B->second.F7; break;\
			case 8: b << B->second.F8; break;\
			}\
		}\
	}\
	return umap.size()>0;\
}\
Afn0dfx_Afn0dFParser_Fx(AP,1)\
Afn0dfx_Afn0dFParser_Fx(AP,2)\
Afn0dfx_Afn0dFParser_Fx(AP,3)\
Afn0dfx_Afn0dFParser_Fx(AP,4)\
Afn0dfx_Afn0dFParser_Fx(AP,5)\
Afn0dfx_Afn0dFParser_Fx(AP,6)\
Afn0dfx_Afn0dFParser_Fx(AP,7)\
Afn0dfx_Afn0dFParser_Fx(AP,8)\
int AP##Afn0dParser::parse(uint8_t *data, int len)\
{\
	int l = len;\
	uint8_t *p = data;\
\
	while(p && l > sizeof(Afn0dfbase))\
	{\
		Afn0dfbase& b = *(Afn0dfbase*)p;\
		Callback func = call[b.Fn()];\
\
		if(func == 0)\
		{\
			return 0;\
		}\
		int r = (this->*func)(p);\
		if(r < sizeof(b))\
		{\
			return 0;\
		}\
		p += r;\
		l -= r;\
	}\
	printf("umap.size(%d)\n", umap.size());\
}\
int_Afn0dFParser_parseFx(AP,1)\
int_Afn0dFParser_parseFx(AP,2)\
int_Afn0dFParser_parseFx(AP,3)\
int_Afn0dFParser_parseFx(AP,4)\
int_Afn0dFParser_parseFx(AP,5)\
int_Afn0dFParser_parseFx(AP,6)\
int_Afn0dFParser_parseFx(AP,7)\
int_Afn0dFParser_parseFx(AP,8)\

AFN0D_PARSER_IMPLEMENTATION(Active)
AFN0D_PARSER_IMPLEMENTATION(Pasive)
